package net.wxxr.http.response;

import net.wxxr.dataparse.model.DataParseCode;
import net.wxxr.dataparse.model.DataParseError;
import net.wxxr.dataparse.model.DataState;
import net.wxxr.http.interfaces.ITag;
import net.wxxr.http.model.pojo.HttpResult;
import net.wxxr.http.util.ErrorCodeUtil;




/**
 * 对http返回的结果进行解析处理，根据解析结果进行不同的回调
 * @author yuanwenfei
 * @param <T>
 */
public abstract class HttpResponse<T> {
	
	protected Object parsedData;
	
	/**
	 * 对响应的数据正确的解析
	 * @param tag
	 * @param result
	 * @param clazz
	 * @author yuanwenfei
	 */
	public void completed(ITag<T> tag, HttpResult result,Object o, Class<T> clazz) {
		
		if(result == null) {//|| clazz == null
			failed(tag, DataParseCode.PARAM_ILLEGAL);//参数不合法
			return;
		}
		
		byte [] retData = result.getData();
		
		//retData为空的处理:读取数据出错
		if(retData == null) {
			failInUIThread(tag, DataParseCode.DATA_READ_FAIL);//读取失败
			return;
		}
		
		try {
		
			if(!parseData(tag, retData,o, clazz)) {
				return;
			}
			
		} catch (Exception e) {
			System.out.println("############### 数据解析失败出现空指针异常############");
			//数据解析失败
			failInUIThread(tag, DataParseCode.DATA_PARSE_FAIL);
			return;
		} catch (OutOfMemoryError e) {
			System.out.println("############### 数据解析失败出现内存溢出############");
			System.out.println(e.getMessage());
			//数据解析失败
			failInUIThread(tag, DataParseCode.DATA_PARSE_FAIL);
			return;
		}
		
		completeInUIThread(tag, DataState.STATE_OK);
	}
	
	public void completed(ITag<T> tag, Object parsedData) {
		this.parsedData = parsedData;
		completeInUIThread(tag, DataState.STATE_OK);
	}
	
	public Object getParseData() {
		return parsedData;
	}
	
	/**
	 * 进行数据解析的操作，若中间出现错误，则需要子类自己处理UI的调用
	 * @param tag
	 * @param data
	 * @param clazz
	 * @return
	 * @throws Exception
	 * @author yuanwenfei
	 */
	protected abstract boolean parseData(ITag<T> tag, byte[] data,Object o, Class<T> clazz) throws Exception, OutOfMemoryError;

	/**
	 * 对错误数据的回调
	 * @param tag
	 * @param parseCode
	 * @author yuanwenfei
	 */
	public void failed(ITag<T> tag, DataParseCode parseCode) {
		failInUIThread(tag, parseCode);
	}

	/**
	 * 对用户取消的情况的回调
	 * @param tag
	 * @author yuanwenfei
	 */
	public void cancelled(ITag<T> tag) {
		cancelInUIThread(tag);
	}

	/**
	 * 在android中使用时，复写此方法，让回调执行在UI线程里面
	 * @param tag
	 * @param ds
	 * @author yuanwenfei
	 */
	@SuppressWarnings({"unchecked" })
	protected void completeInUIThread(final ITag<T> tag, final DataState ds) {
		if(parsedData != null) {
			if(null !=tag)tag.refreshUI((T)parsedData, ds);
		} else {
			failInUIThread(tag, DataParseCode.DATA_PARSE_FAIL);
		}
	}
	
	private void failInUIThread(final ITag<T> tag, final DataParseCode parseCode) {
		final DataParseError error = ErrorCodeUtil.getErrorByCode(parseCode);
		failInUIThread(tag, error);
	}
	
	/**
	 * 在android中使用时，复写此方法，让回调执行在UI线程里面
	 * @param tag
	 * @param error
	 * @author yuanwenfei
	 */
	protected void failInUIThread(final ITag<T> tag, final DataParseError error) {
		if(null != tag){
			if(!tag.refreshError(error)) {
				copeWithError(error);
			}
		}
	}
	
	/**
	 * 对错误结果的统一处理，比如打印出来，在android中可能会toast出来
	 * @param error
	 * @author yuanwenfei
	 */
	protected void copeWithError(final DataParseError error) {
		System.out.println(error.getErrMsg());
	}
	
	/**
	 * 在android中使用时，复写此方法，让回调执行在UI线程里面
	 * @param tag
	 * @author yuanwenfei
	 */
	protected void cancelInUIThread(final ITag<T> tag) {
		if(null != tag){
			tag.refreshCancel();
		}
	}
	
}
